package v1alpha1

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// BladeChaosSpec defines the desired state of BladeChaos
type BladeChaosSpec struct {
	ContainerSelector `json:",inline"`

	// Duration represents the duration of the chaos action
	// +optional
	Duration *string `json:"duration,omitempty" webhook:"Duration"`

	// Target represents the target about blade chaos action
	Target BladeTarget `json:"target"`

	// Action defines the specific blade chaos action.
	Action BladeAction `json:"action"`

	// +optional TODO 是否支持用key对应value为空，代表无参数标签?
	PrepareFlags map[string]string `json:"prepareFlags,omitempty"`

	// +optional
	CreateFlags map[string]string `json:"createFlags,omitempty"`

	// RemoteCluster represents the remote cluster where the chaos will be deployed
	// +optional
	RemoteCluster string `json:"remoteCluster,omitempty"`
}

// BladeTarget represents the target about blade chaos action
type BladeTarget string

const (
	BladeTargetJvm      BladeTarget = "jvm"
	BladeTargetCk       BladeTarget = "ck"
	BladeTargetDruid    BladeTarget = "druid"
	BladeTargetDubbo    BladeTarget = "dubbo"
	BladeTargetEs       BladeTarget = "es"
	BladeTargetFeign    BladeTarget = "feign"
	BladeTargetGateway  BladeTarget = "gateway"
	BladeTargetHbase    BladeTarget = "hbase"
	BladeTargetHttp     BladeTarget = "http"
	BladeTargetJedis    BladeTarget = "jedis"
	BladeTargetKafka    BladeTarget = "kafka"
	BladeTargetLettuce  BladeTarget = "lettuce"
	BladeTargetLog      BladeTarget = "log"
	BladeTargetMongodb  BladeTarget = "mongodb"
	BladeTargetMysql    BladeTarget = "mysql"
	BladeTargetPsql     BladeTarget = "psql"
	BladeTargetRabbitmq BladeTarget = "rabbitmq"
	BladeTargetRedisson BladeTarget = "redisson"
	BladeTargetRocketmq BladeTarget = "rocketmq"
	BladeTargetSecurity BladeTarget = "security"
	BladeTargetServlet  BladeTarget = "servlet"
	BladeTargetTars     BladeTarget = "tars"
	BladeTargetZk       BladeTarget = "zk"
)

// BladeAction represents the chaos action about blade
type BladeAction string

const (
	BladeActionCodeCacheFilling       BladeAction = "CodeCacheFilling"
	BladeActionOutOfMemoryError       BladeAction = "OutOfMemoryError"
	BladeActionCpufullload            BladeAction = "cpufullload"
	BladeActionDelay                  BladeAction = "delay"
	BladeActionFullGc                 BladeAction = "full-gc"
	BladeActionReturn                 BladeAction = "return"
	BladeActionScript                 BladeAction = "script"
	BladeActionThreadfull             BladeAction = "threadfull"
	BladeActionThrowCustomException   BladeAction = "throwCustomException"
	BladeActionThrowDeclaredException BladeAction = "throwDeclaredException"
)

// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="action",type=string,JSONPath=`.spec.action`
// +kubebuilder:printcolumn:name="duration",type=string,JSONPath=`.spec.duration`
// +chaos-mesh:experiment

// BladeChaos is the Schema for the bladechaos API
type BladeChaos struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   BladeChaosSpec   `json:"spec,omitempty"`
	Status BladeChaosStatus `json:"status,omitempty"`
}

var _ InnerObjectWithCustomStatus = (*BladeChaos)(nil)
var _ InnerObjectWithSelector = (*BladeChaos)(nil)
var _ InnerObject = (*BladeChaos)(nil)

func init() {
	SchemeBuilder.Register(&BladeChaos{}, &BladeChaosList{})
}

// GetSelectorSpecs is a getter for selectors
func (obj *BladeChaos) GetSelectorSpecs() map[string]interface{} {
	return map[string]interface{}{
		".": &obj.Spec.ContainerSelector,
	}
}

func (obj *BladeChaos) GetCustomStatus() interface{} {
	return &obj.Status.BladeChaosCustomStatus
}
